﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Xentrix;
using System.ComponentModel;

namespace Vara.Location
{
    //Note: this should be removed from this separate project and added as a class within Vara_Data_Layer - perhaps with a web service method
    public class Location_Controller : ILocationActions
    {
        #region ILocationActions Implementations
        private static List<ILocation> _LocationList = null;
        public List<ILocation> Locations
        {
            get
            {
                if (_LocationList == null)
                {
                    _LocationList = new List<ILocation>();
                    Refresh_Locations_List();
                }
                return _LocationList;
            }
        }
        public virtual ILocation InsertLocation(ILocation location)
        {
            int intNewId = 0;
            using (SqlEngine NewSqlEngine = new SqlEngine("AssetTracking"))
            {
                SqlEngineProcedureVariable[] var = {
                                                    new SqlEngineProcedureVariable("@ID",intNewId,SqlDbType.Int),
                                                    new SqlEngineProcedureVariable("@LocationName",location.Name.ToString()),
                                                    new SqlEngineProcedureVariable("@address1",location.Address1.ToString()),
                                                    new SqlEngineProcedureVariable("@address2",location.Address2.ToString()),
                                                    new SqlEngineProcedureVariable("@address3",location.Address3.ToString()),
                                                    new SqlEngineProcedureVariable("@postcode",location.Postcode.ToString())
                                                   };

                intNewId = ((int)NewSqlEngine.ExecuteProcedure("Insert_Location", var).Rows[0]["ID"]);
            }
            Refresh_Locations_List();
            return ReturnLocation(intNewId, false);
        }
        public virtual void UpdateLocation(ILocation location)
        {
            // if instantiated with an id
            if (location.ID > 0)
            {
                //setup and call update procedure
                using (SqlEngine NewSqlEngine = new SqlEngine("AssetTracking"))
                {
                    SqlEngineProcedureVariable[] var = {
                                                            new SqlEngineProcedureVariable("@ID",location.ID,SqlDbType.Int),
                                                            new SqlEngineProcedureVariable("@LocationName", location.Name.ToString()),
                                                            new SqlEngineProcedureVariable("@address1",location.Address1.ToString()),
                                                            new SqlEngineProcedureVariable("@address2", location.Address2.ToString()),
                                                            new SqlEngineProcedureVariable("@address3", location.Address3.ToString()),
                                                            new SqlEngineProcedureVariable("@postcode", location.Postcode.ToString())
                                                       };
                    NewSqlEngine.ExecuteProcedure("Update_Location", var);
                }
                Refresh_Locations_List();
            }
        }
        public virtual void DeleteLocation(ILocation location)
        {
            //if instanitated with an id
            if (location.ID > 0)
            {
                //call delete procedure
                using (SqlEngine NewSqlEngine = new SqlEngine("AssetTracking"))
                { 
                    SqlEngineProcedureVariable[] var = {
                                                        new SqlEngineProcedureVariable("@id", location.ID, SqlDbType.Int),
                                                        new SqlEngineProcedureVariable("@internal", location.IsInternal ? "1" : "0")};
                }
                Refresh_Locations_List();
            }
        }
        public virtual ILocation ReturnLocation(int id, bool isInternal)
        {
            // find location in the list with a delegate
            return this.Locations.Find(new Predicate<ILocation>(delegate(ILocation l)
            {
                return l.ID == id && l.IsInternal == isInternal;
            }));
        }
        public virtual void Refresh_Locations_List()
        {
            // get the table of locations
            DataTable DataTableOfLocations = null;

            using (SqlEngine NewSqlEngine = new SqlEngine("AssetTracking"))
            {
                DataTableOfLocations = NewSqlEngine.ExecuteProcedure("Return_Locations");

                if (DataTableOfLocations.Rows.Count > 0)
                {
                    _LocationList = new List<ILocation>();
                    foreach (DataRow R in DataTableOfLocations.Rows)
                    {
                        ILocation NewILocation;
                        if (((bool)R["InternalLocation"]))
                            NewILocation = new InternalLocation((int)R["LocationId"]);
                        else
                            NewILocation = new ExternalLocation((int)R["LocationId"]);

                        NewILocation.Name = R["LocationName"].ToString();
                        NewILocation.Address1 = R["Address1"].ToString();
                        NewILocation.Address2 = R["Address2"].ToString();
                        NewILocation.Address3 = R["Address3"].ToString();
                        NewILocation.Postcode = R["Postcode"].ToString();
                        NewILocation.AdditionalField1 = (R["RoomId"].ToString() == "") ? "0" : R["RoomId"].ToString();
                        NewILocation.AdditionalField2 = R["RoomName"].ToString();
                        _LocationList.Add(NewILocation);
                    }
                }
            }
        }
        public virtual DataTable Search_Locations(string SearchCriteria)
        {
            DataView DataViewLocations = new DataView();
            DataViewLocations.Table = ConvertToDataTable(this.Locations);
            DataViewLocations.RowFilter = string.Format("AdditionalField2 LIKE '%{0}%' OR Name LIKE '%{0}%' OR Address1 LIKE '%{0}%' OR Address2 LIKE '%{0}%' OR Address3 LIKE '%{0}%' OR PostCode LIKE '%{0}%'", SearchCriteria);
            return DataViewLocations.ToTable();
        }
        #endregion
        #region Originally Vara Utility methods
        public static DataTable ConvertToDataTable<T>(IList<T> lst)
        {
            //create DataTable Structure
            DataTable DataTableToReturn = CreateTable<T>();
            Type entType = typeof(T);

            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);
            //get the list item and add into the list
            foreach (T item in lst)
            {
                DataRow row = DataTableToReturn.NewRow();
                foreach (PropertyDescriptor prop in properties)
                {
                    row[prop.Name] = prop.GetValue(item);
                }
                DataTableToReturn.Rows.Add(row);
            }

            return DataTableToReturn;
        }
        public static DataTable CreateTable<T>()
        {
            //T –> ClassName
            Type entType = typeof(T);
            //set the datatable name as class name
            DataTable DataTableToReturn = new DataTable(entType.Name);
            //get the property list
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);
            foreach (PropertyDescriptor prop in properties)
            {
                //add property as column
                DataTableToReturn.Columns.Add(prop.Name, prop.PropertyType);
            }
            return DataTableToReturn;
        }
        #endregion
    }
}
